﻿using Otter;
using System;
using System.Collections.Generic;
using System.Linq;

namespace LeRenard.ScriptWars.Ui.Otter2DClient.Scenes
{
    public class GameScene : Scene
    {
        private DateTime _lastUpdated;
        private Text _numberOfTurns;
        private Gradient _background;
        private IList<Image> _entities;

        public GameScene()
        {
            _entities = new List<Image>();

            _lastUpdated = DateTime.Now;

            _background = new Gradient(
                Global.Window.Width, Global.Window.Height,
                Color.Black, Color.Black,
                new Color("444444"), new Color("555555")
            );
            AddGraphic(_background);

            // TODO: calculate the biggest possible grid size for given resolution.
            var gridBlockSize = (float)CalculateGridBlockSize();
            var offsetX = (Global.Window.Width / 2f) - ((gridBlockSize * Global.Game.Grid.Size.Width) / 2f);
            var offsetY = (Global.Window.Height / 2f) - ((gridBlockSize * Global.Game.Grid.Size.Height) / 2f);
            for(int y = 0; y < Global.Game.Grid.Size.Height; y++) {
                for (int x = 0; x < Global.Game.Grid.Size.Width; x++ ) {
                    var rectangle = Image.CreateRectangle((int)gridBlockSize, Color.White);
                    rectangle.Alpha = .5f;
                    rectangle.X = offsetX + (rectangle.Width * x) + (x * 1);
                    rectangle.Y = offsetY + (rectangle.Height * y) + (y * 1);
                    rectangle.OutlineColor = Color.Black;                    
                    AddGraphic(rectangle);
                }
            }            

            _numberOfTurns = new Text("TURN #{0}".FormatWith(Global.Game.Turns.ToString("0000")), "../../Assets/Fonts/OldComputerSt.ttf", 22);
            _numberOfTurns.TextStyle = TextStyle.Bold;
            _numberOfTurns.Smooth = true;
            _numberOfTurns.X = Global.Window.Width - _numberOfTurns.Width - 16;
            _numberOfTurns.Y = 16;            
            AddGraphic(_numberOfTurns);
        }

        public override void Update()
        {
            base.Update();

            if (IsTimeToForNextRound()) {
                // Next turn
                Global.Game.Next();                
                _lastUpdated = DateTime.Now;

                // Update background
                var current = Global.Game.CurrentTurnCell.Value;
                if (current != null) {
                    var hexColor = System.Drawing.ColorTranslator.ToHtml(current.Script.Color).Replace("#", "");
                    var c = new Color(hexColor);
                    _numberOfTurns.Color = c;
                }

                // Update counter (string)
                _numberOfTurns.String = "TURN #{0}".FormatWith(Global.Game.Turns.ToString("0000"));          
                                              
                // Draw entities
                // -> Remove old graphics
                foreach (var entity in _entities) {
                    RemoveGraphic(entity);
                }
                _entities.Clear();
                // -> Add new ones
                var gridBlockSize = (float)CalculateGridBlockSize();
                var offsetX = (Global.Window.Width / 2f) - ((gridBlockSize * Global.Game.Grid.Size.Width) / 2f);
                var offsetY = (Global.Window.Height / 2f) - ((gridBlockSize * Global.Game.Grid.Size.Height) / 2f);
                for (int y = 0; y < Global.Game.Grid.Size.Height; y++) {
                    for (int x = 0; x < Global.Game.Grid.Size.Width; x++) {
                        var script = Global.Game.Grid.Layout[y, x].Value;
                        if (script != null) {
                            var hexColor = System.Drawing.ColorTranslator.ToHtml(script.Script.Color).Replace("#", "");
                            var rectangle = Image.CreateRectangle((int)gridBlockSize, new Otter.Color(hexColor));
                            rectangle.Alpha = .5f;
                            rectangle.X = offsetX + (rectangle.Width * x) + (x * 1);
                            rectangle.Y = offsetY + (rectangle.Height * y) + (y * 1);
                            _entities.Add(rectangle);
                            AddGraphic(rectangle);
                        }
                    }
                }
             
            }                        
        }

        private bool IsTimeToForNextRound()
        {
            var timePassed = DateTime.Now.Subtract(_lastUpdated);
            if (timePassed.TotalMilliseconds > 50) {
                return true;
            }

            return false;
        }

        private int CalculateGridBlockSize()
        {
            var possibleSize = 1;
            var again = true;

            while (again) {
                var possibleGridWidth = ((possibleSize+1) * Global.Game.Grid.Size.Width) + (16 * 4);
                var possibleGridHeight = ((possibleSize+1) * Global.Game.Grid.Size.Height) + (16 * 6);

                if (possibleGridWidth >= Global.Window.Width || possibleGridHeight >= Global.Window.Height) {
                    again = false;
                }

                possibleSize++;
            }

            return possibleSize;
        }

        public int Fibonacci(int n)
        {
            int a = 0;
            int b = 1;
            // In N steps compute Fibonacci sequence iteratively.
            for (int i = 0; i < n; i++) {
                int temp = a;
                a = b;
                b = temp + b;
            }
            return a;
        }
    }
}
